#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string>
#include <sys/epoll.h>
#include <unistd.h>
#include <strings.h>
#include <nlohmann/json.hpp>
#include <vector>
using std::vector;
using std::string;

using std::cout;
using std::endl;
using json = nlohmann::json;
class Train
{
    int length;
    int id;
    string msg;
};
int main(int argc, char* argv[])
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1)
    {
        perror("socket");
        return 0;
    }

    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8888);
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    
    int ret = connect(sockfd,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
    if(ret == -1)
    {
        perror("connect");
        return 0;
    }
    
    int epfd = epoll_create(1);
    if(epfd == -1)
    {
        perror("epoll_create");
        return 0;
    }
    
    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = sockfd;
    epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&event);

    struct epoll_event ev2;
    ev2.events = EPOLLIN;
    ev2.data.fd = STDIN_FILENO;
    epoll_ctl(epfd,EPOLL_CTL_ADD,STDIN_FILENO,&ev2);

    char buf[100000];
    ssize_t sret;
    
    struct epoll_event readySet[10];
    int flag = 1;
    while(1)
    {
        bzero(buf,sizeof(buf));
        int readyNum = epoll_wait(epfd,readySet,10,3000);
        for(int i = 0; i < readyNum; ++i)
        {
            bzero(buf,sizeof(buf));
            if(readySet[i].data.fd == sockfd)
            {
                int length;
                int id;
                //QUE:服务器发回来的数据特别大,buf装不下怎么半?
                read(sockfd,&length,sizeof(int));
                read(sockfd,&id,sizeof(int));
                if(length > 0)
                {
                    //cout << "测试退出length:" << length << endl;
                    read(sockfd,buf,length);
                    string msg(buf);
                    if(id == 100)
                    {
                        cout << msg << endl;
                        cout << "请选取推荐的关键词[回车:退出]" << endl;
                        flag = 2;
                    }
                    else
                    {
                        //将json字符串转成vector<string>;
                        json tmp = json::parse(msg);
                        vector<string> vec = tmp.get<vector<string>>();
                        for(auto &ele : vec)
                        {
                            cout << ele << endl;
                        }
                        cout << "请输入查询词[回车-退出]: " << endl;
                        flag = 1;
                    }
                    length = 0;
                }
                else
                {
                    goto out;
                }
                
                
            }
            else if(readySet[i].data.fd == STDIN_FILENO)
            {
                //客户端准备发数据
                sret = read(STDIN_FILENO,buf,sizeof(buf));
                if(sret != 0)
                {
                    buf[sret-1] = '\0';
                }
                cout << buf << endl;
                if(flag == 1)
                {
                    int length = (sret >  0 ? sret - 1 : sret);
                    int id;
                    if(length == 0)
                    {
                        id = 3;
                        goto out;
                    }
                    else
                    {
                        id = flag;
                    }
                    //将buf数据转成json字符串
                    json js = string(buf);//这样构造是个否有问题
                    string js_msg = js.dump();
                    length = js_msg.size();

                    string msg;
                    msg.append((char*)&length,4);
                    msg.append((char*)&id,4);
                    msg.append(js_msg.c_str(),length);
                    write(sockfd,msg.c_str(),msg.size());
                    length = 0;
                }
                else
                {
                    
                    int length = (sret >  0 ? sret - 1 : sret);
                    int id;
                    if(length == 0)
                    {
                        id = 3;
                        goto out;
                    }
                    else
                    {
                        id = flag;
                    }
                    //将buf数据转成json字符串
                    json js = string(buf);//这样构造是个否有问题
                    string js_msg = js.dump();
                    length = js_msg.size();
                    
                    string msg;
                    msg.append((char*)&length,4);
                    msg.append((char*)&id,4);
                    msg.append(js_msg.c_str(),length);
                    write(sockfd,msg.c_str(),msg.size());
                    flag = 1;
                    length = 0;
                }
            }
        }
    }
out:
    close(sockfd);
    return 0;
}
